using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Ltf.Remoting.RemoteEvents;
using Microsoft.TeamFoundation.VersionControl.Client;
using Ltf.Remoting.TeamFoundation;
using Ltf.Remoting.TFAccess;
using System.Collections;
using Ltf.MonitorLizard.Helpers;
using System.IO;

namespace Ltf.MonitorLizard.Forms
{
	[FormType(FormTypes.NewLabels)]

	public partial class NewLabel : Form
	{
		private Workspace workspace;
		private string path;
		private string serverPath;
		private TFServerConnection connection;

		public List<VirtualViewItem> labelViewItems=new List<VirtualViewItem>();
		Dictionary<ListView, int> sortColumnIndex;
		Dictionary<ListView, bool> sortDesc;
		Dictionary<ListView, List<VirtualViewItem>> sortitems;


		public NewLabel(Workspace workspace, string path)
		{
			connection = ServerConnections.GetConnectionForPath(path);
			InitializeComponent();
			lvwItems.VirtualListSize = 0;
			this.workspace = workspace;
			sortColumnIndex = new Dictionary<ListView, int>();
			sortColumnIndex.Add(lvwItems, 0);
			sortDesc = new Dictionary<ListView, bool>();
			sortDesc.Add(lvwItems, false);
			sortitems = new Dictionary<ListView, List<VirtualViewItem>>();
			sortitems.Add(lvwItems, labelViewItems);
			serverPath = workspace.TryGetServerItemForLocalItem(path);
			txtOwner.Text = workspace.OwnerName;
			cmbRecursionType.Text = "Full";
			LoadProjectsCombo(connection);
		}

		public NewLabel(string[] pathList, LizardEventArgs args)
		{
			TFServerConnection connection = ServerConnections.GetConnectionForPath(pathList[0]);
			InitializeComponent();
			lvwItems.VirtualListSize = 0;
			sortColumnIndex = new Dictionary<ListView, int>();
			sortColumnIndex.Add(lvwItems, 0);
			sortDesc = new Dictionary<ListView, bool>();
			sortDesc.Add(lvwItems, false);
			sortitems = new Dictionary<ListView, List<VirtualViewItem>>();
			sortitems.Add(lvwItems, labelViewItems);
			path = pathList[0];
			cmbRecursionType.Text = "Full";
			workspace = connection.GetWorkspace(path);
			if (workspace != null)
			{
				serverPath = workspace.TryGetServerItemForLocalItem(path);
				txtOwner.Text = workspace.OwnerName;
			}
			else
			{
				txtOwner.Text = Environment.UserDomainName + "\\" + Environment.UserName;
			}
			LoadProjectsCombo(connection);
		}

		private void LoadProjectsCombo(TFServerConnection connection)
		{
			using (HourGlass hg = new HourGlass(this))
			{
				VersionControlServer vcServer = connection.VersionControlServer;
				TeamProject[] projects = vcServer.GetAllTeamProjects(true);
				cmbScope.Items.Clear();
				cmbScope.Items.Add("$/");
				foreach (TeamProject tp in projects)
				{
					cmbScope.Items.Add("$/"+tp.Name);
					if (serverPath.StartsWith("$/" + tp.Name))
						cmbScope.SelectedIndex = cmbScope.Items.Count - 1;
				}
				if (cmbScope.SelectedIndex == -1)
				{
					cmbScope.SelectedIndex = 0;
				}
			}
		}

		void lsvChanges_ColumnClick(object sender, ColumnClickEventArgs e)
		{
			ListView lv = sender as ListView;
			lv.Columns[sortColumnIndex[lv]].ImageKey = null;
			if (sortColumnIndex[lv] == e.Column)
				sortDesc[lv] = !sortDesc[lv];
			else
			{
				sortDesc[lv] = false;
				sortColumnIndex[lv] = e.Column;
			}

			SortListView(lv);
		}

		private void SortListView(ListView lv)
		{
			IComparer<VirtualViewItem> c = new VirtualViewItem.Sorter(sortColumnIndex[lv], sortDesc[lv]);
			List<VirtualViewItem> list = new List<VirtualViewItem>(sortitems[lv]);
			list.Sort(c);
			sortitems[lv] = list;

			labelViewItems = sortitems[lv];

			lv.Invalidate();
			lv.Refresh();
		}

		private void cbtTFScopeFinder_Click(object sender, EventArgs e)
		{
			string projectPath=txtItems.Text;
			if (cmbVersion1.SelectedIndex > 1)
			{
				int v;
				if (int.TryParse(cmbVersion1.Text, out v))
					projectPath = LizardFileAccess.SetPathVersion(projectPath, v);
			}
			TFProjectBrowser tfpb = new TFProjectBrowser(txtItems.Text, workspace);
			tfpb.ShowDialog();

			txtItems.Text = tfpb.ProjectPath;
			cmbVersion1.Text = tfpb.ProjectVersion == 0 ? "Latest" : tfpb.ProjectVersion.ToString();
		}

		private void txtItems_TextChanged(object sender, EventArgs e)
		{
			LizardFileAccess.LoadVersions(connection, cmbVersion1, txtItems.Text);
		}


		

		private void btnCreate_Click(object sender, EventArgs e)
		{
			if (CreateLabel())
				Close();

		}

		private bool CreateLabel()
		{
			try
			{
				VersionControlLabel vcl = new VersionControlLabel(workspace.VersionControlServer, txtLabelName.Text, txtOwner.Text, cmbScope.Text, txtComments.Text);
				List<LabelItemSpec> liss = new List<LabelItemSpec>();
				foreach (VirtualViewItem vvi in labelViewItems)
				{
					ItemSpec itemSpec = new ItemSpec(vvi.Items[0], RecursionType.None);
					VersionSpec versionSpec = new ChangesetVersionSpec(int.Parse(vvi.Items[1]));
					LabelItemSpec lis = new LabelItemSpec(itemSpec, versionSpec, false);
					liss.Add(lis);
				}

				workspace.VersionControlServer.CreateLabel(vcl, liss.ToArray(), LabelChildOption.Merge);
				return true;
			}
			catch (Exception ex)
			{
				MessageBox.Show("Could not create the label due to the following error:\r\n{0}", "Create Label Failed");
				return false;
			}
		}

		private void btnPreview_Click(object sender, EventArgs e)
		{
			if (txtItems.Text == string.Empty)
			{
				MessageBox.Show("Please select a repository path to base the label on.", "No Path For Preview");
				return;
			}
			RecursionType rt=RecursionType.Full;
			string rtText=cmbRecursionType.Text;
			switch (rtText)
			{
				case "None":
					rt = RecursionType.None;
					break;
				case "Full":
					rt = RecursionType.Full;
					break;
				case "One Level":
					rt = RecursionType.OneLevel;
					break;
			}
			VersionSpec vs=VersionSpec.Latest;
			int v=0;
			if (int.TryParse(cmbVersion1.Text,out v))
				vs=new ChangesetVersionSpec(v);

			ItemSet iss =workspace.VersionControlServer.GetItems(txtItems.Text,vs,rt);
			FileIcons fi = new FileIcons(fileImages);
			lvwItems.SmallImageList = fileImages;
			labelViewItems = new List<VirtualViewItem>();
			foreach (Item i in iss.Items)
			{
				VirtualViewItem vvi = new VirtualViewItem();
				vvi.Text = i.ServerItem;
				vvi.Items = new string[] { i.ServerItem, i.ChangesetId.ToString() };
				if (i.ItemType == ItemType.Folder)
					vvi.ImageKey = "$folder";
				else
				{
					vvi.ImageKey = fi.LoadIconForFileExtension(System.IO.Path.GetExtension(i.ServerItem));
				}
				labelViewItems.Add(vvi);
			}
			sortitems[lvwItems] = labelViewItems;
			lvwItems.VirtualListSize = labelViewItems.Count;
			btnAdd.Enabled = labelViewItems.Count > 0;
			btnRemove.Enabled = labelViewItems.Count > 0;
		}

		private void btnClose_Click(object sender, EventArgs e)
		{
			Close();
		}

		private void lvwItems_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)
		{
			e.Item = labelViewItems[e.ItemIndex].ConvertToListViewItem();
		}

		private void btnAdd_Click(object sender, EventArgs e)
		{
			TFProjectBrowser tfpb = new TFProjectBrowser(txtItems.Text, ItemType.Any, workspace, true);
			tfpb.ShowDialog();
			Ltf.MonitorLizard.Helpers.FileIcons fileIcons = new Ltf.MonitorLizard.Helpers.FileIcons(fileImages);
			Dictionary<string, VirtualViewItem> listItems = new Dictionary<string, VirtualViewItem>();
			foreach (VirtualViewItem vvi in labelViewItems)
				listItems.Add(vvi.Items[0], vvi);
			foreach (Item i in tfpb.GetSelectedItems())
			{
				if (!listItems.ContainsKey(i.ServerItem))
				{
					LabelUpdateOperation op = new LabelUpdateOperation();
					op.Path = i.ServerItem;
					op.versionSpec = new ChangesetVersionSpec(i.ChangesetId);
					op.Type = LabelUpdateOperationType.Add;
					VirtualViewItem vvi = new VirtualViewItem();
					vvi.Items = new string[] { i.ServerItem, i.ChangesetId.ToString() };
					if (i.ItemType == ItemType.Folder)
						vvi.ImageKey = "$folder";
					else
						vvi.ImageKey = fileIcons.LoadIconForFileExtension(System.IO.Path.GetExtension(i.ServerItem));
					listItems.Add(i.ServerItem, vvi);
					//pendingUpdates.Enqueue(op);
					//btnUpdate.Enabled = true;
				}
			}
			labelViewItems = new List<VirtualViewItem>( listItems.Values);
			lvwItems.VirtualListSize = labelViewItems.Count;
			sortitems[lvwItems] = labelViewItems;
			SortListView(lvwItems);
		}

		private void btnRemove_Click(object sender, EventArgs e)
		{
			List<VirtualViewItem> listItems = new List<VirtualViewItem>(labelViewItems);
			int offset = 0;
			while (lvwItems.SelectedIndices.Count > 0)
			{
				int idx = lvwItems.SelectedIndices[0];
				lvwItems.SelectedIndices.Remove(idx);
				LabelUpdateOperation op = new LabelUpdateOperation();
				op.Path = labelViewItems[idx].Items[0];
				op.versionSpec = new ChangesetVersionSpec(int.Parse(labelViewItems[idx].Items[1]));
				op.Type = LabelUpdateOperationType.Remove;
	//			pendingUpdates.Enqueue(op);
				listItems.RemoveAt(idx - offset++);
	//			btnUpdate.Enabled = true;
			}
			labelViewItems = listItems;
			lvwItems.VirtualListSize = listItems.Count;
			sortitems[lvwItems] = labelViewItems;
			SortListView(lvwItems);
			lvwItems.RedrawItems(0, listItems.Count - 1, false);
		}
	}
}